package com.jwb.intercepter;

import java.io.PrintWriter;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.annotation.PostConstruct;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSONObject;
import com.jwb.util.AES256;
import com.jwb.util.ToolsUtil;

public class DealInterceptor implements HandlerInterceptor {  

	private final Logger log = LoggerFactory.getLogger(this.getClass().getName());

    public static final Set<String> excludeUrlSet = new CopyOnWriteArraySet<>();
    
    public static String exclude_url;
    
    public static String im_prefix;
    
    public static String auth_cookie_name;
    
    public static String auth_cookie_key;
    
    public static String cors_hosts;
    
    @PostConstruct
    public void postConstruct() {
    	try{
    		auth_cookie_name = ToolsUtil.getProp("im.properties", "auth_cookie_name");
    		auth_cookie_key = ToolsUtil.getProp("im.properties", "auth_cookie_key");
    		exclude_url= ToolsUtil.getProp("im.properties", "exclude_url");    		
    		cors_hosts = ToolsUtil.getProp("im.properties", "cors_hosts"); 
    		im_prefix = ToolsUtil.getProp("im.properties", "im_prefix"); 
    		
	        if(!StringUtils.isEmpty(exclude_url)) {
	            String[] excludeUrlArray = exclude_url.split(",");
	            for (String excludeUrl : excludeUrlArray) {
	                excludeUrlSet.add(excludeUrl.trim());
	            }
	        }
    	}catch(Exception e){
    		log.info("postConstruct (DealInterceptor)"+e.getMessage());
    	}
    }
  
    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
    try
    {
    	log.info("DealInterceptor preHandle " + request.getRequestURL().toString() + "," + request.getRequestURI());
    	HttpSession session = request.getSession();
    	if(session.getAttribute("userId")==null){
    		String uri = request.getRequestURI(); 
    		uri = uri.substring(uri.indexOf("/", 1)).trim();
    		String prefix = uri.substring(0,uri.indexOf("/", 1)).trim();
    		if(im_prefix.indexOf(prefix)>-1){
    			response.setHeader("Access-Control-Allow-Origin",cors_hosts);
    	        response.setHeader("Access-Control-Allow-Methods","*");
    	        response.setHeader("Access-Control-Allow-Headers", "Content-Type,x-requested-with,Authorization,token,Accept,Referer,User-Agent");
    	        response.setHeader("Access-Control-Allow-Credentials", "true");
    	        if(request.getMethod().equals("OPTIONS")){
    	            response.setStatus(HttpServletResponse.SC_OK);
    	            return false;
    	        }
    	        Integer currentUserId = null;
	    		if (!excludeUrlSet.contains(uri)){
	    			Cookie authCookie = getAuthCookie(request);
	                if (authCookie == null) {
	                    response.setStatus(403);
	                    response.getWriter().write("Not logged in.");
	                    return false;
	                }
	
	                try {
	                    currentUserId = getCurrentUserId(authCookie);
	//                    serverApiParams.setCurrentUserId(currentUserId);
	                } catch (Exception e) {
	                    log.error("获取currentUserId异常,error: " + e.getMessage(), e);
	                }
	
	                if (currentUserId == null) {
	                    response.setStatus(500);
	                    response.getWriter().write("Invalid cookie value");
	                    return false;
	                }                     
	    		} 
	    		// ServerApiParamHolder.put(serverApiParams);
	    		request.getSession().setAttribute("currentUserId", ""+currentUserId);	    		
	    		return true; 
    		}else{
	    		response.setCharacterEncoding("UTF-8");
	    		response.setContentType("application/json;charset=utf-8");
	    		PrintWriter pw = response.getWriter();
	    		JSONObject jsobject = new JSONObject();
	    		jsobject.put("respCode", "-999");
	    		jsobject.put("respDesc", "系统超时,重新登陆");
	    		log.info("preHandle "+jsobject.toString());
	    		pw.append(jsobject.toString());
	    		pw.close();
	    		return false;
    		}
    	}else{    	
    		return true;
    	}	
    	
    	
    }
    catch(Exception e)
    {
    	e.printStackTrace();
    	throw new Exception (e.toString());
    	
    	
    }
    	  
    }  
  
    
    private Cookie getAuthCookie(HttpServletRequest request) throws Exception{
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                log.info("getAuthCookie " + cookie.getName() + "=" + cookie.getValue());
                if (cookie.getName().equals(ToolsUtil.getProp("im.properties", "auth_cookie_name"))) { 
                    return cookie;
                }
            }
        }
        return null;
    }
    
    
    private Integer getCurrentUserId(Cookie authCookie) throws Exception {
        String cookieValue = authCookie.getValue();
        String decrypt = AES256.decrypt(cookieValue.getBytes(),auth_cookie_key); 
        assert decrypt != null;
        String[] split = decrypt.split("\\|");
        if (split.length != 3) {
            throw new RuntimeException("Invalid cookie value!");
        }
        return Integer.parseInt(split[1]);
    }
    
    
    @Override  
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {  
    	log.info("DealInterceptor postHandle " + request.getRequestURL().toString() + "," + request.getRequestURI());
    }  
  
    @Override  
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {  
    	log.info("DealInterceptor afterCompletion " + request.getRequestURL().toString() + "," + request.getRequestURI());
    }  
}  